using System;
using System.ComponentModel;
using System.Threading;
using Microsoft.TeamFoundation.Build.Client;
using Microsoft.TeamFoundation.Client;
using RollManager.Library.ActionSteps.BaseClasses;

namespace RollManager.Library.ActionSteps
{
    [Serializable]
    public class QueueBuildStep : TeamBuildStep
    {
        private bool m_waitForBuild = false;
        private QueuePriority m_priority = QueuePriority.Normal;

        [DisplayName( "Queue Priority" )]
        [Description( "The priority of the build to run." )]
        public QueuePriority QueuePriority
        {
            get
            {
                return m_priority;
            }
            set
            {
                m_priority = value;
            }
        }

        [DisplayName( "Wait For Build" )]
        [Description( "Whether to wait for the build to finish." )]
        public bool WaitForBuild
        {
            get
            {
                return m_waitForBuild;
            }
            set
            {
                m_waitForBuild = value;
            }
        }

        public override string Name
        {
            get { return "Queue Build"; }
        }

        protected override void Run()
        {
            IBuildServer buildServer = getBuildServer();

            // Queue build
            IBuildDefinition buildDef = buildServer.GetBuildDefinition( TeamProject, BuildName );
            IBuildRequest buildRequest = buildDef.CreateBuildRequest();
            buildRequest.Priority = m_priority;
            IQueuedBuild build = buildServer.QueueBuild( buildRequest, QueueOptions.None );

            int queuePosition = build.QueuePosition;
            QueueStatus status = build.Status;
            Progress.AddFormat( "Build is in position {0} in the queue.", queuePosition );

            if( !m_waitForBuild )
            {
                return;
            }

            // Wait for build.  Report queue advancements.
            while( build.Status != QueueStatus.Completed )
            {
                if( build.QueuePosition == -1 )
                {
                    break;
                }

                if( build.QueuePosition != queuePosition )
                {
                    queuePosition = build.QueuePosition;
                    Progress.AddFormat( "Build is in position {0} in the queue.", queuePosition );
                }

                if( build.Status != status )
                {
                    status = build.Status;
                    Progress.AddFormat( "Build is in position {0} in the queue with status {1}", queuePosition, status.ToString() );
                }

                Thread.Sleep( 3000 );
                build.Refresh( QueryOptions.All );
            }

            // Report completion.
            if( build.Build.Status == BuildStatus.Succeeded )
            {
                Progress.Add( "Build finished successfully." );
            }
            else 
            {
                throw new Exception( string.Format(
                    "Build {0} stopped with status of {1}", build.Build.BuildNumber, build.Build.Status.ToString() ) );
            }
        }

        protected override void Simulate()
        {
            IBuildServer buildServer = getBuildServer();

            IBuildDefinition buildDef = buildServer.GetBuildDefinition( TeamProject, BuildName );
            if( buildDef == null )
            {
                throw new Exception( string.Format( "Couldn't create build request for {0}.", TeamUrl ) );
            }

            Progress.AddFormat( "Simulated queuing build {0} in {1} on {2}", BuildName, TeamProject, TeamUrl );
        }
    }
}
